Passed
Pull Request — master (#1)
by Muhammad Dyas
01:35
created

vote-card.ts ➔ cardHeader   A

Complexity

Conditions 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 14
c 0
b 0
f 0
rs 10
cc 1
1
import {choiceSection} from './helpers/vote';
2
import {ICON_URL_48X48} from './config/default';
3
import {chat_v1 as chatV1} from 'googleapis/build/src/apis/chat/v1';
4
import {PollState, Voter} from './helpers/interfaces';
5
6
/**
7
 * Builds the card header including the question and author details.
8
 *
9
 * @param {string} topic - Topic of the poll
10
 * @param {string} author - Display name of user that created the poll
11
 * @returns {chatV1.Schema$GoogleAppsCardV1CardHeader} card header
12
 */
13
function cardHeader(topic: string, author: string): chatV1.Schema$GoogleAppsCardV1CardHeader {
14
  return {
15
    title: topic,
16
    subtitle: `Posted by ${author}`,
17
    imageUrl: ICON_URL_48X48,
18
    imageType: 'CIRCLE',
19
  };
20
}
21
22
/**
23
 * Builds the section header using decoratedText instead of card header if the topic title is too long
24
 *
25
 * @param {string} topic - Topic of the poll
26
 * @param {string} author - Display name of user that created the poll
27
 * @returns {chatV1.Schema$GoogleAppsCardV1Section} card section
28
 */
29
function sectionHeader(topic: string, author: string): chatV1.Schema$GoogleAppsCardV1Section {
30
  return {
31
    widgets: [
32
      {
33
        'decoratedText': {
34
          'text': topic,
35
          'wrapText': true,
36
          'bottomLabel': `Posted by ${author}`,
37
          'startIcon': {
38
            'altText': 'Absolute Poll',
39
            'iconUrl': ICON_URL_48X48,
40
            'imageType': 'SQUARE',
41
          },
42
        },
43
      },
44
    ],
45
  };
46
}
47
48
/**
49
 * Builds the configuration form.
50
 *
51
 * @param {object} state - Current state of poll
52
 * @param {object} state.author - User that submitted the poll
53
 * @param {string} state.topic - Topic of poll
54
 * @param {string[]} state.choices - Text of choices to display to users
55
 * @param {object} state.votes - Map of cast votes keyed by choice index
56
 * @param {object} state.choiceCreator - Map of cast votes keyed by choice index
57
 * @param {boolean} state.anon - Is anonymous?(will save voter name or not)
58
 * @param {boolean} state.optionable - Can other user add other option?
59
 * @returns {chatV1.Schema$CardWithId} card
60
 */
61
export function buildVoteCard(state: PollState) {
62
  const sections = [];
63
  const stateString = JSON.stringify(state);
64
65
  const votes: Array<Array<Voter>> = Object.values(state.votes!);
66
  const totalVotes: number = votes.reduce((sum, vote) => sum + vote.length, 0);
67
  for (let i = 0; i < state.choices.length; ++i) {
68
    const creator = state.choiceCreator?.[i];
69
    const section = choiceSection(i, state, totalVotes, stateString, creator);
70
    sections.push(section);
71
  }
72
  const buttons = [];
73
  if (state.optionable) {
74
    buttons.push({
75
      'text': 'Add Option',
76
      'onClick': {
77
        'action': {
78
          'function': 'add_option_form',
79
          'interaction': 'OPEN_DIALOG',
80
          'parameters': [],
81
        },
82
      },
83
    });
84
  }
85
  if (state.closable) {
86
    buttons.push(
87
      {
88
        'text': 'Close Poll',
89
        'onClick': {
90
          'action': {
91
            'function': 'close_poll_form',
92
            'interaction': 'OPEN_DIALOG',
93
            'parameters': [],
94
          },
95
        },
96
      });
97
  }
98
99
  if (buttons.length > 0) {
100
    sections.push(
101
      {
102
        'widgets': [
103
          {
104
            'buttonList': {
105
              buttons,
106
            },
107
          },
108
        ],
109
      });
110
  }
111
  const card: chatV1.Schema$CardWithId = {
112
    'cardId': 'unique-card-id',
113
    'card': {
114
      sections,
115
    },
116
  };
117
  const authorName = state.author?.displayName ?? '';
118
  if (state.topic.length > 40) {
119
    const widgetHeader = sectionHeader(state.topic, authorName);
120
    card.card!.sections = [widgetHeader, ...sections];
121
  } else {
122
    card.card!.header = cardHeader(state.topic, authorName);
123
  }
124
  return card;
125
}
126